/*
 * 
 */

package movgen;

import java.util.List;

import state.GameState;



/**
 * This class is used to conduct a performance test on the move generation
 * process.
 */
public class Perft {
    private long nodes;
    private long captures;
    private long checks;
    private long enPassant;
    private long castles;
    private long promotions;
    private GameState state;
    private boolean debug=true;
    
    public Perft(GameState state)
    {
        this.state = state;
    }

    public void test(int depth)
    {
        nodes = 0;
        checks = 0;
        captures = 0;
        enPassant = 0;
        castles = 0;
        promotions = 0;
        
        long start = new java.util.Date().getTime();
        
        crawl(state, depth);
        
        long end = new java.util.Date().getTime();
        
        if (debug) System.out.println("nodes="+ nodes + ", captures=" + captures + ", ep=" + enPassant 
             + ", castles=" + castles + ", promotions=" + promotions + ", checks=" + checks);
        
        float time = (float)(end-start)/1000;
        
       if (debug)  System.out.println("time=" + time + ", nps=" + (float)nodes/time);
    }

    private void crawl(GameState state, int depth)
    {
        if(depth == 0)
        {
            return;
        }
        else
        {
        	
        	
            List<Integer> moves = Util.getLegalMoveList(state);
            int flags=state.flags;
            long hash=state.hash;
            
            for(int move : moves)
            {
            	//GameState newState = new GameState(state);
            	//move.print();
            	state.make(move);
               
                if(depth == 1)
                {
                    nodes++;
                    int type = Move2.moveType(move);
                    switch(type) {
                    	case Move2.kcastle: case Move2.qcastle : 
                    	
                    		castles++;
                    		break;
                    	case Move2.captureNoPromotion: 
                    		captures++;
                    		break;
                    	
                    	case Move2.capturePromotionQueen:
                    		captures++;
                    		promotions++;
                    		break;
                    	
                    	case Move2.simplePromotionQueen:
                    		promotions++;
                    		break;
                    	case Move2.epCapture:
                    		enPassant++;
                    		captures++;
                    }
                    
                   if(state.isInCheck( state.color))
                        checks++;
                }
                crawl(state,depth-1);
                state.unmake(move,flags,hash);
            }
        }
    }
  
	public long getNodes() {
		return nodes;
	}

	public void setNodes(long nodes) {
		this.nodes = nodes;
	}

	public long getCaptures() {
		return captures;
	}

	public void setCaptures(long captures) {
		this.captures = captures;
	}

	public long getChecks() {
		return checks;
	}

	public void setChecks(long checks) {
		this.checks = checks;
	}

	public long getEnPassant() {
		return enPassant;
	}

	public void setEnPassant(long enPassant) {
		this.enPassant = enPassant;
	}

	public long getCastles() {
		return castles;
	}

	public void setCastles(long castles) {
		this.castles = castles;
	}

	public long getPromotions() {
		return promotions;
	}

	public void setPromotions(long promotions) {
		this.promotions = promotions;
	}

	public GameState getState() {
		return state;
	}

	public void setState(GameState state) {
		this.state = state;
	}
}
